home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
gnu
/
oleo-1_4.lha
/
oleo-1.4
/
lists.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-27
|
25KB
|
1,304 lines
/* Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc.
This file is part of Oleo, the GNU Spreadsheet.
Oleo is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Oleo is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Oleo; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "funcdef.h"
#define obstack_chunk_alloc ck_malloc
#define obstack_chunk_free free
#include "obstack.h"
#include "sysdef.h"
#include "global.h"
#include "cell.h"
#include "ref.h"
#include "window.h"
#include "io-term.h"
#include "io-abstract.h"
#define ROW_BUF 3
#define COL_BUF 2
#define MAX MAX_ROW
#define MIN MIN_ROW
static struct obstack find_stack;
#if 1
#define malloc_chain_check(x)
#endif
#ifdef __GNUC__
#define inline __inline__
#else
#define inline
#endif
#ifdef TEST_ME
typedef unsigned char CELLREF;
typedef unsigned int size_t;
#define ck_malloc malloc
extern void *malloc ();
#define MIN 1
#define MAX 65535
#endif
struct list
{
CELLREF lo, hi;
struct list *next;
char mem[1];
};
struct find
{
struct find *next;
CELLREF lo, hi, cur;
struct list **start;
struct list *curptr;
CELLREF left;
void *ret;
char fini;
int ele;
};
struct find *finds = 0;
#ifdef __STDC__
static inline void
flush (struct list *ptr)
#else
static inline void
flush (ptr)
struct list *ptr;
#endif
{
struct list *nxt;
while (ptr)
{
nxt = ptr->next;
free (ptr);
ptr = nxt;
}
}
#ifdef __STDC__
static inline void
resync (struct list *tofree, struct list *new, int ele)
#else
static inline void
resync (tofree, new, ele)
struct list *tofree;
struct list *new;
int ele;
#endif
{
struct find *findp;
if (ele == sizeof (struct cell)
&& my_cell
&& (char *) my_cell >= tofree->mem
&& (char *) my_cell <= tofree->mem + ele * (1 + tofree->hi - tofree->lo))
my_cell = (struct cell *) (new->mem + ele * (cur_row - new->lo));
for (findp = finds; findp; findp = findp->next)
{
if (tofree == findp->curptr)
{
CELLREF hi;
findp->curptr = new;
findp->ret = new->mem + (findp->cur - new->lo) * ele;
hi = (findp->hi < new->hi ? findp->hi : new->hi);
if (findp->cur < hi)
findp->left = hi - findp->cur;
}
}
free (tofree);
}
#ifdef __STDC__
static inline void *
find (CELLREF pos, struct list *ptr, int ele)
#else
static inline void *
find (pos, ptr, ele)
CELLREF pos;
struct list *ptr;
int ele;
#endif
{
for (; ptr; ptr = ptr->next)
{
if (ptr->lo > pos)
break;
if (ptr->hi >= pos)
return ptr->mem + (pos - ptr->lo) * ele;
}
return 0;
}
#ifdef __STDC__
static inline void *
make (CELLREF pos, struct list **prevp, int ele, int buf)
#else
static inline void *
make (pos, prevp, ele, buf)
CELLREF pos;
struct list **prevp;
int ele;
int buf;
#endif
{
CELLREF lo, hi;
size_t size;
struct list *ptr;
while (*prevp && (*prevp)->next && (*prevp)->next->lo < pos)
prevp = &((*prevp)->next);
/* Was it easy? */
if (*prevp && (*prevp)->lo <= pos && (*prevp)->hi >= pos)
return (*prevp)->mem + (pos - (*prevp)->lo) * ele;
lo = (pos < MIN + buf) ? MIN : pos - buf;
hi = (pos > MAX - buf) ? MAX : pos + buf;
if (!*prevp
|| ((*prevp)->hi < lo - 1
&& (!(*prevp)->next
|| (*prevp)->next->lo - 1 > hi)))
{
/* Allocate a whole new structure */
size = (1 + hi - lo) * ele;
ptr = ck_malloc (sizeof (struct list) + size);
ptr->lo = lo;
ptr->hi = hi;
if (*prevp && (*prevp)->hi < lo)
{
ptr->next = (*prevp)->next;
(*prevp)->next = ptr;
}
else
{
ptr->next = *prevp;
*prevp = ptr;
}
bzero (ptr->mem, size);
malloc_chain_check (1);
}
else if ((*prevp)->lo > lo)
{
/* Stretch one down a bit to fit */
hi = (*prevp)->hi;
size = (1 + hi - lo) * ele;
ptr = ck_malloc (sizeof (struct list) + size);
ptr->lo = lo;
ptr->hi = hi;
ptr->next = (*prevp)->next;
bcopy ((*prevp)->mem, ptr->mem + ((*prevp)->lo - ptr->lo) * ele, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
bzero (ptr->mem, ((*prevp)->lo - ptr->lo) * ele);
resync (*prevp, ptr, ele);
*prevp = ptr;
malloc_chain_check (1);
}
else if ((*prevp)->hi < hi && (*prevp)->next && (*prevp)->next->lo <= hi)
{
/* Merge this one and the one after it */
size = (1 + (*prevp)->next->hi - (*prevp)->lo) * ele;
ptr = ck_malloc (sizeof (struct list) + size);
ptr->lo = (*prevp)->lo;
ptr->hi = (*prevp)->next->hi;
ptr->next = (*prevp)->next->next;
bcopy ((*prevp)->mem, ptr->mem, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
bzero (ptr->mem + (1 + (*prevp)->hi - ptr->lo) * ele, ((*prevp)->next->lo - (*prevp)->hi) * ele);
bcopy ((*prevp)->next->mem,
ptr->mem + ((*prevp)->next->lo - ptr->lo) * ele,
(1 + (*prevp)->next->hi - (*prevp)->next->lo) * ele);
resync ((*prevp)->next, ptr, ele);
resync (*prevp, ptr, ele);
*prevp = ptr;
malloc_chain_check (1);
}
else if ((*prevp)->hi < hi)
{
/* stretch this one up a bit */
size = (1 + hi - (*prevp)->lo) * ele;
ptr = ck_malloc (sizeof (struct list) + size);
ptr->lo = (*prevp)->lo;
ptr->hi = hi;
ptr->next = (*prevp)->next;
bcopy ((*prevp)->mem, ptr->mem, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
bzero (ptr->mem + (1 + (*prevp)->hi - ptr->lo) * ele, (hi - (*prevp)->hi) * ele);
resync (*prevp, ptr, ele);
*prevp = ptr;
malloc_chain_check (1);
}
else
ptr = *prevp;
#ifdef TEST
if (ptr->lo > pos || ptr->hi < pos)
panic ("Make at %u not in %u %u", pos, ptr->lo, ptr->hi);
#endif
return ptr->mem + (pos - ptr->lo) * ele;
}
#ifdef __STDC__
static inline void *
find_rng (struct list **start, CELLREF lo, CELLREF hi, int ele)
#else
static inline void *
find_rng (start, lo, hi, ele)
struct list **start;
CELLREF lo;
CELLREF hi;
int ele;
#endif
{
struct list *ptr;
struct find *f;
f = (struct find *)obstack_alloc (&find_stack, sizeof (struct find));
f->lo = lo;
f->hi = hi;
f->ele = ele;
f->start = start;
for (ptr = *start; ptr; ptr = ptr->next)
if (ptr->hi >= lo)
break;
if (ptr && ptr->lo <= hi)
{
f->cur = (ptr->lo > lo ? ptr->lo : lo);
f->curptr = ptr;
f->ret = ptr->mem + (f->cur - ptr->lo) * ele;
f->left = 1 + (f->hi < ptr->hi ? f->hi : ptr->hi) - f->cur;
f->fini = 0;
}
else
f->fini = 1;
f->next = finds;
finds = f;
return f;
}
#ifdef __STDC__
static inline void *
make_rng (struct list **start, CELLREF lo, CELLREF hi, int ele, int buf)
#else
static inline void *
make_rng (start, lo, hi, ele, buf)
struct list **start;
CELLREF lo;
CELLREF hi;
int ele;
int buf;
#endif
{
struct list **prevp;
struct list *ptr;
size_t size;
struct find *f;
f = (struct find *)obstack_alloc (&find_stack, sizeof (struct find));
f->lo = f->cur = lo;
f->hi = hi;
f->left = 1 + hi - lo;
f->fini = 0;
f->ele = ele;
f->start = start;
lo = lo <= MIN + buf ? MIN : lo - buf;
hi = hi >= MAX - buf ? MAX : hi + buf;
for (prevp = start; *prevp && (*prevp)->hi < lo - 1; prevp = &((*prevp)->next))
;
ptr = *prevp;
if (!*prevp || (*prevp)->lo - 1 > hi)
{
/* Allocate the whole thing */
size = (1 + hi - lo) * ele;
ptr = ck_malloc (sizeof (struct list) + size);
ptr->lo = lo;
ptr->hi = hi;
ptr->next = *prevp;
bzero (ptr->mem, size);
if (*prevp && (*prevp)->hi < lo)
{
ptr->next = (*prevp)->next;
(*prevp)->next = ptr;
}
else
{
ptr->next = *prevp;
*prevp = ptr;
}
*prevp = ptr;
malloc_chain_check (1);
}
else
{
if ((*prevp)->lo > lo)
{
/* Stretch this one down a bit */
size = (1 + (*prevp)->hi - lo) * ele;
ptr = ck_malloc (sizeof (struct list) + size);
ptr->lo = lo;
ptr->hi = (*prevp)->hi;
ptr->next = (*prevp)->next;
bcopy ((*prevp)->mem,
ptr->mem + ((*prevp)->lo - ptr->lo) * ele,
(1 + (*prevp)->hi - (*prevp)->lo) * ele);
bzero (ptr->mem, ((*prevp)->lo - lo) * ele);
resync (*prevp, ptr, ele);
*prevp = ptr;
malloc_chain_check (1);
}
while ((*prevp)->hi < hi && (*prevp)->next && (*prevp)->next->lo <= hi)
{
/* Merge this one and the one after it */
/* Repeat as needed */
size = (1 + (*prevp)->next->hi - (*prevp)->lo) * ele;
ptr = ck_malloc (sizeof (struct list) + size);
ptr->lo = (*prevp)->lo;
ptr->hi = (*prevp)->next->hi;
ptr->next = (*prevp)->next->next;
bcopy ((*prevp)->mem, ptr->mem, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
bzero (ptr->mem + (1 + (*prevp)->hi - ptr->lo) * ele, ((*prevp)->next->lo - (*prevp)->hi) * ele);
bcopy ((*prevp)->next->mem,
ptr->mem + ((*prevp)->next->lo - ptr->lo) * ele,
(1 + (*prevp)->next->hi - (*prevp)->next->lo) * ele);
resync ((*prevp)->next, ptr, ele);
resync (*prevp, ptr, ele);
*prevp = ptr;
malloc_chain_check (1);
}
if ((*prevp)->hi < hi)
{
/* stretch this one up a bit */
size = (1 + hi - (*prevp)->lo) * ele;
ptr = ck_malloc (sizeof (struct list) + size);
ptr->lo = (*prevp)->lo;
ptr->hi = hi;
ptr->next = (*prevp)->next;
bcopy ((*prevp)->mem, ptr->mem, (1 + (*prevp)->hi - (*prevp)->lo) * ele);
bzero (ptr->mem + (1 + (*prevp)->hi - ptr->lo) * ele, (hi - (*prevp)->hi) * ele);
resync (*prevp, ptr, ele);
*prevp = ptr;
malloc_chain_check (1);
}
}
#ifdef TEST
if (ptr->lo > f->lo || ptr->hi < f->hi)
panic ("Vector of %u-%u not big enough for %u-%u", (*prevp)->lo, (*prevp)->hi, f->lo, f->hi);
#endif
f->curptr = ptr;
f->ret = ptr->mem + (f->cur - ptr->lo) * ele;
f->next = finds;
finds = f;
return f;
}
#ifdef __STDC__
static inline void *
next_rng (struct find *f, CELLREF *posp)
#else
static inline void *
next_rng (f, posp)
struct find *f;
CELLREF *posp;
#endif
{
void *ret;
struct find *next;
if (!f)
return 0;
if (!f->fini)
{
if (f->left)
{
--(f->left);
fini:
if (posp)
*posp = f->cur;
f->cur++;
ret = f->ret;
f->ret = (char *) (f->ret) + f->ele;
return ret;
}
if (f->curptr->hi < f->hi)
{
f->curptr = f->curptr->next;
if (f->curptr && f->curptr->lo <= f->hi)
{
f->ret = f->curptr->mem;
f->left = (f->hi < f->curptr->hi ? f->hi : f->curptr->hi) - f->curptr->lo;
f->cur = f->curptr->lo;
goto fini;
}
}
}
next = f->next;
obstack_free (&find_stack, f);
finds = next;
return 0;
}
struct cf
{
struct cf *next;
struct find *rows, *cols;
int make;
};
static struct cf *fp;
static struct list *the_cols;
static struct find *w_find;
static struct find *h_find;
static struct list *wids, *hgts;
void
init_cells ()
{
obstack_begin (&find_stack, sizeof (struct find) * 15);
the_cols = 0;
wids = 0;
hgts = 0;
}
#ifdef __STDC__
void
flush_everything (void)
#else
void
flush_everything ()
#endif
{
struct list *ptr, *nxt;
int n;
flush_variables ();
for (ptr = the_cols; ptr; ptr = nxt)
{
nxt = ptr->next;
for (n = 0; n <= ptr->hi - ptr->lo; n++)
flush (*(struct list **) (ptr->mem + (n * sizeof (struct list *))));
free (ptr);
}
the_cols = 0;
flush (wids);
wids = 0;
flush (hgts);
hgts = 0;
flush_fonts ();
}
#if __STDC__
struct cell *
find_cell (CELLREF row, CELLREF col)
#else
struct cell *
find_cell (row, col)
CELLREF row;
CELLREF col;
#endif
{
void **v;
v = find (col, the_cols, sizeof (void *));
return v ? find (row, *v, sizeof (struct cell)) : 0;
}
#if __STDC__
struct cell *
find_or_make_cell (CELLREF row, CELLREF col)
#else
struct cell *
find_or_make_cell (row, col)
CELLREF row;
CELLREF col;
#endif
{
struct list **v;
v = make (col, &the_cols, sizeof (struct list *), COL_BUF);
return make (row, v, sizeof (struct cell), ROW_BUF);
}
#ifdef __STDC__
void
find_cells_in_range (struct rng *r)
#else
void
find_cells_in_range (r)
struct rng *r;
#endif
{
struct cf *new;
struct list **firstcol;
new = (struct cf *)obstack_alloc (&find_stack, sizeof (struct cf));
new->make = 0;
new->next = fp;
fp = new;
new->rows = find_rng (&the_cols, r->lc, r->hc, sizeof (void *));
firstcol = next_rng (new->rows, 0);
if (firstcol)
new->cols = find_rng (firstcol, r->lr, r->hr, sizeof (struct cell));
else
new->cols = 0;
}
#ifdef __STDC__
void
make_cells_in_range (struct rng *r)
#else
void
make_cells_in_range (r)
struct rng *r;
#endif
{
struct cf *new;
struct list **firstcol;
new = (struct cf *)obstack_alloc (&find_stack, sizeof (struct cf));
new->make = 1;
new->next = fp;
fp = new;
new->rows = make_rng (&the_cols, r->lc, r->hc, sizeof (void *), ROW_BUF);
firstcol = next_rng (new->rows, 0);
new->cols = make_rng (firstcol, r->lr, r->hr, sizeof (struct cell), COL_BUF);
}
#ifdef __STDC__
struct cell *
next_cell_in_range (void)
#else
struct cell *
next_cell_in_range ()
#endif
{
struct cell *ret;
void *new_row;
for (;;)
{
if (ret = next_rng (fp->cols, 0))
return ret;
new_row = next_rng (fp->rows, 0);
if (!new_row)
{
struct cf *old;
old = fp->next;
obstack_free (&find_stack, fp);
fp = old;
return 0;
}
fp->cols = fp->make ? make_rng (new_row, fp->cols->lo, fp->cols->hi, sizeof (struct cell), ROW_BUF)
: find_rng (new_row, fp->cols->lo, fp->cols->hi, sizeof (struct cell));
}
}
#ifdef __STDC__
struct cell *
next_row_col_in_range (CELLREF *rowp, CELLREF *colp)
#else
struct cell *
next_row_col_in_range (rowp, colp)
CELLREF *rowp;
CELLREF *colp;
#endif
{
struct cell *ret;
struct list **new_row;
for (;;)
{
if (ret = next_rng (fp->cols, rowp))
{
*colp = fp->rows->cur - 1;
return ret;
}
new_row = next_rng (fp->rows, colp);
if (!new_row)
{
struct cf *old;
old = fp->next;
obstack_free (&find_stack, fp);
fp = old;
return 0;
}
fp->cols = fp->make ? make_rng (new_row, fp->cols->lo, fp->cols->hi, sizeof (struct cell), ROW_BUF)
: find_rng (new_row, fp->cols->lo, fp->cols->hi, sizeof (struct cell));
}
}
#ifdef __STDC__
void
no_more_cells (void)
#else
void
no_more_cells ()
#endif
{
struct cf *old;
/* This relies on knowing that the obstack contains
* the current find (struct cf) underneath two associated
* `struct find's.
* Here, we pop all those frames, and then free them at once.
*/
old = fp->next;
finds = finds->next->next;
obstack_free (&find_stack, fp);
fp = old;
}
#ifdef __STDC__
CELLREF
max_row (CELLREF col)
#else
CELLREF
max_row (col)
CELLREF col;
#endif
{
struct list **ptr;
ptr = find (col, the_cols, sizeof (void *));
if (!ptr || !*ptr)
return MIN;
while ((*ptr)->next)
ptr = &((*ptr)->next);
return (*ptr)->hi;
}
#ifdef __STDC__
CELLREF
max_col (CELLREF row)
#else
CELLREF
max_col (row)
CELLREF row;
#endif
{
struct list *ptr;
if (!the_cols)
return MIN;
for (ptr = the_cols; ptr->next; ptr = ptr->next)
;
return ptr->hi;
}
#ifdef __STDC__
CELLREF
highest_row (void)
#else
CELLREF
highest_row ()
#endif
{
void *f;
struct list **ptr;
CELLREF hi = MIN;
f = find_rng (&the_cols, MIN, MAX, sizeof (void *));
while (ptr = next_rng (f, 0))
{
if (*ptr)
{
while ((*ptr)->next)
ptr = &((*ptr)->next);
if ((*ptr)->hi > hi)
hi = (*ptr)->hi;
}
}
return hi;
}
#ifdef __STDC__
CELLREF
highest_col (void)
#else
CELLREF
highest_col ()
#endif
{
struct list *ptr;
if (!the_cols)
return MIN;
for (ptr = the_cols; ptr->next; ptr = ptr->next)
;
return ptr->hi;
}
/* Routines for dealing with the widths of columns. . . */
#ifdef __STDC__
int
get_width (CELLREF col)
#else
int
get_width (col)
CELLREF col;
#endif
{
int *ptr;
ptr = find (col, wids, sizeof (int));
if (!ptr || !*ptr)
return default_width;
return (*ptr) - 1;
}
#ifdef __STDC__
int
get_nodef_width (CELLREF col)
#else
int
get_nodef_width (col)
CELLREF col;
#endif
{
int *ptr;
ptr = find (col, wids, sizeof (int));
return ptr ? *ptr : 0;
}
#ifdef __STDC__
void
set_width (CELLREF col, int wid)
#else
void
set_width (col, wid)
CELLREF col;
int wid;
#endif
{
int *ptr;
ptr = make (col, &wids, sizeof (int), COL_BUF);
*ptr = wid;
}
#ifdef __STDC__
void
find_widths (CELLREF lo, CELLREF hi)
#else
void
find_widths (lo, hi)
CELLREF lo;
CELLREF hi;
#endif
{
w_find = find_rng (&wids, lo, hi, sizeof (int));
}
#ifdef __STDC__
int
next_width (CELLREF *posp)
#else
int
next_width (posp)
CELLREF *posp;
#endif
{
int *ptr;
do
ptr = next_rng (w_find, posp);
while (ptr && !*ptr);
return ptr ? *ptr : 0;
}
#ifdef __STDC__
static void
do_shift (int over, CELLREF lo, CELLREF hi, struct list **start, int buf)
#else
static void
do_shift (over, lo, hi, start, buf)
int over;
CELLREF lo;
CELLREF hi;
struct list **start;
int buf;
#endif
{
CELLREF pos;
int w;
int *ptr;
int inc;
struct list *p;
if (!*start)
return;
for (p = *start; p->next; p = p->next)
;
if (hi > p->hi)
hi = p->hi;
if (over > 0)
{
pos = hi;
hi = lo;
lo = pos;
inc = -1;
}
else
inc = 1;
if (inc > 0)
{
if (lo > hi)
return;
}
else if (hi > lo)
return;
for (pos = lo;; pos += inc)
{
ptr = find (pos, *start, sizeof (int));
w = ptr ? *ptr : 0;
ptr = w ? make (pos + over, start, sizeof (int), buf) :
find (pos + over, *start, sizeof (int));
if (w || (ptr && *ptr))
*ptr = w;
if (pos == hi)
break;
}
for (pos = hi + over;;)
{
pos += inc;
ptr = find (pos, *start, sizeof (int));
if (ptr)
*ptr = 0;
if (pos == hi)
break;
}
}
#ifdef __STDC__
void
shift_widths (int over, CELLREF lo, CELLREF hi)
#else
void
shift_widths (over, lo, hi)
int over;
CELLREF lo;
CELLREF hi;
#endif
{
do_shift (over, lo, hi, &wids, COL_BUF);
}
/* This inserts lines in which formulas can be displayed.
* It probably ought to be 1 or 0.
*/
int display_formula_mode = 0;
/* Routines for dealing with the height of rows
*/
#ifdef __STDC__
int
get_height (CELLREF row)
#else
int
get_height (row)
CELLREF row;
#endif
{
int *ptr;
ptr = find (row, hgts, sizeof (int));
if (!ptr || !*ptr)
return default_height;
return *ptr - 1 + (display_formula_mode && using_curses);
}
#ifdef __STDC__
int
get_nodef_height (CELLREF row)
#else
int
get_nodef_height (row)
CELLREF row;
#endif
{
int *ptr;
ptr = find (row, hgts, sizeof (int));
return ptr ? *ptr : 0;
}
#ifdef __STDC__
void
set_height (CELLREF row, int hgt)
#else
void
set_height (row, hgt)
CELLREF row;
int hgt;
#endif
{
int *ptr;
ptr = make (row, &hgts, sizeof (int), ROW_BUF);
*ptr = hgt;
}
float height_scale = 1.;
float width_scale = 1.;
float user_height_scale = 1.;
float user_width_scale = 1.;
#ifdef __STDC__
void
set_user_scales (double hs, double ws)
#else
void
set_user_scales (hs, ws)
double hs;
double ws;
#endif
{
user_height_scale = hs;
user_width_scale = ws;
io_repaint ();
}
#ifdef __STDC__
int
get_scaled_height (CELLREF r)
#else
int
get_scaled_height (r)
CELLREF r;
#endif
{
return ((user_height_scale <= 0.)
? 1
: (int) (get_height (r) * height_scale * user_height_scale));
}
#ifdef __STDC__
int
get_scaled_width (CELLREF c)
#else
int
get_scaled_width (c)
CELLREF c;
#endif
{
return ((user_width_scale <= 0.)
? 1
: (int)(get_width (c) * width_scale * user_width_scale));
}
#ifdef __STDC__
void
find_heights (CELLREF lo, CELLREF hi)
#else
void
find_heights (lo, hi)
CELLREF lo;
CELLREF hi;
#endif
{
h_find = find_rng (&hgts, lo, hi, sizeof (int));
}
#ifdef __STDC__
int
next_height (CELLREF *posp)
#else
int
next_height (posp)
CELLREF *posp;
#endif
{
int *ptr;
do
ptr = next_rng (h_find, posp);
while (ptr && !*ptr);
return ptr ? *ptr : 0;
}
#ifdef __STDC__
void
shift_heights (int dn, CELLREF lo, CELLREF hi)
#else
void
shift_heights (dn, lo, hi)
int dn;
CELLREF lo;
CELLREF hi;
#endif
{
do_shift (dn, lo, hi, &hgts, ROW_BUF);
}
#ifdef TEST
extern char *bname[];
extern void dbg_print_ref_fm ();
extern void dbg_print_ref_to ();
extern void dbg_print_formula ();
void
dbg_print_cell (cp)
CELL *cp;
{
char *ptr1, *ptr2;
char tmpbuf[30];
switch (GET_TYP (cp))
{
case 0:
ptr1 = "(null)";
ptr2 = "";
break;
case TYP_FLT:
sprintf (tmpbuf, "Float: %.16g", cp->cell_flt);
ptr1 = tmpbuf;
ptr2 = "";
break;
case TYP_INT:
sprintf (tmpbuf, "Int: %ld", cp->cell_int);
ptr1 = tmpbuf;
ptr2 = "";
break;
case TYP_ERR:
sprintf (tmpbuf, "Error: %d: ", cp->cell_err);
ptr1 = tmpbuf;
ptr2 = ename[cp->cell_err];
break;
case TYP_BOL:
sprintf (tmpbuf, "Bool: %d: ", cp->cell_bol);
ptr1 = tmpbuf;
ptr2 = bname[cp->cell_bol];
break;
case TYP_STR:
sprintf (tmpbuf, "String: %p: ", cp->cell_str);
ptr1 = tmpbuf;
ptr2 = cp->cell_str;
break;
default:
sprintf (tmpbuf, "Unknown: %d", GET_TYP (cp));
ptr1 = tmpbuf;
ptr2 = "";
break;
}
io_text_line (" Cell %p: flg %#lx fm %p to %p fa %p cy %d val %s%s",
cp, cp->cell_flags, cp->cell_refs_from, cp->cell_refs_to,
cp->cell_formula, cp->cell_cycle, ptr1, ptr2);
dbg_print_ref_fm (cp->cell_refs_from);
dbg_print_ref_to (cp->cell_refs_to);
dbg_print_formula (cp->cell_formula);
}
void
dbg_print_list (ptr, ele, txt, prsub)
struct list *ptr;
int ele;
char *txt;
void (*prsub) ();
{
CELLREF pos;
while (ptr)
{
io_text_line ("%s %p: lo %u hi %u nxt %p mem %p", txt, ptr, ptr->lo, ptr->hi, ptr->next, &(ptr->mem[0]));
pos = ptr->lo;
for (;;)
{
(*prsub) (ptr->mem + ele * (pos - ptr->lo));
if (pos == ptr->hi)
break;
pos++;
}
ptr = ptr->next;
}
}
static void
dbg_pr_row (p)
VOIDSTAR p;
{
io_text_line (" %p", p);
}
void
dbg_print_rows (pos)
CELLREF pos;
{
dbg_print_list (the_cols, sizeof (struct list *), "row", dbg_pr_row);
}
static void
dbg_pr_all (p)
VOIDSTAR p;
{
struct list **ptr;
io_text_line (" %p", p);
ptr = p;
dbg_print_list (*ptr, sizeof (struct cell), " col",
(void (*)(void *)) dbg_print_cell);
}
void
dbg_print_array ()
{
dbg_print_list (the_cols, sizeof (struct list *), "row", dbg_pr_all);
}
void
dbg_print_cols (pos)
CELLREF pos;
{
/* struct list **ptr;
ptr=find(...);
if(...); */
}
#endif
#ifdef TEST_ME
main ()
{
char buf[100];
static void *vec[10];
static siz[10];
char *ret;
int n;
int t;
int hi, lo;
CELLREF pos;
int z;
while (printf ("-->"), gets (buf))
{
n = buf[1] - '0';
switch (buf[0])
{
case 'i':
if (sscanf (&buf[2], "%d %d", &siz[n], &t) < 1)
{
printf ("No size?\n");
break;
}
vec[n] = list_init (siz[n], t);
printf ("vec %d init'd to %lx with siz %u and buf %d\n", n, vec[n], siz[n], t);
break;
case 'f':
ret = find (vec[n], atoi (&buf[2]));
if (ret)
{
printf ("Found at %lx ", ret);
for (t = 0; t < siz[n]; t++)
printf ("%x ", ret[t]);
printf ("\n");
}
else
printf ("Not found\n");
break;
case 'F':
if (sscanf (&buf[2], "%d %d", &lo, &hi) != 2)
{
printf ("Faild to scan\n");
break;
}
find_rng (vec[n], lo, hi);
while (ret = next_rng (&pos))
{
printf ("Found %u at %lx ", pos, ret);
for (t = 0; t < siz[n]; t++)
printf ("%x ", ret[t]);
printf ("\n");
}
break;
case 'm':
ret = make (vec[n], atoi (&buf[2]));
if (ret)
{
z = atoi (&buf[4]);
printf ("Made at %lx ", ret);
for (t = 0; t < siz[n]; t++)
{
printf ("%x(%x) ", ret[t], z);
ret[t] = z;
}
printf ("\n");
}
else
printf ("Failed!!\n");
break;
case 'M':
z = 0;
if (sscanf (&buf[2], "%d %d %d", &lo, &hi, &z) < 2)
{
printf ("Scan failed\n");
break;
}
make_rng (vec[n], lo, hi);
while (ret = next_rng (&pos))
{
printf ("Found %u at %lx ", pos, ret);
for (t = 0; t < siz[n]; t++)
{
printf ("%x(%x) ", ret[t], z);
ret[t] = z;
}
if (z)
z++;
printf ("\n");
}
break;
case 'q':
exit (0);
default:
printf ("Unknown command!\n");
}
}
}
#endif